/*
* @Author:Iyoole,
* @Time  :2017-11-08
* @Description:自由组合模块
* @git   :
* */
;!function(win){
    'use strict';
    var d=document,modules,
        config={
            modules:{},
            status:{},//模块状态
            timeout:10
        },
        f={
            gu:function(){
                var h = location.hash.split("?"),
                    n = h[0].split("#")[1],//路由地址
                    p = h[1] ? h[1].split("&") : [],//参数内容
                    q = {};
                for(var x = 0;x<p.length ; x++){
                    var m = p[x].split("=");
                    q[m[0]] = m[1]
                }
                return  {
                    path:n,
                    query:q
                }
            },
            isFun:function(o){
                return Object.prototype.toString.call(o)==='[object Function]'
            },
            isArr:function(o){
                return Object.prototype.toString.call(o)==='[object Array]'
            }
        },
        fui=function(){
            this.v='2.0.0';
            modules=this.device()?pcModules:mobileModules;
            for(var o in comModules){
                modules[o]=comModules[o]
            }
        },
        error=function(er){
            win.console&&console.error&&console.error(er)
        },
        getPath=function(){
            var j=d['scripts'],jp=j[j['length']-1]['src'],sp=jp.substring(0,jp.lastIndexOf('/'));
            return sp.substring(0,sp.lastIndexOf('/') + 1);
        }(),
        isOpera=typeof opera !=='undefined'&&opera.toString()==='[object Opera]',
        comModules={//pc和移动通用模块
            JsTpl:'modules/JsTpl',      //模版
            jquery:'modules/jquery'     //三方库
        },
        pcModules={//PC端独立模块
            layer:'modules/pc/layer',   //弹窗
            JsForm:'modules/pc/JsForm', //表单
            JsPage:'modules/pc/JsPage', //分页
            jeDate:'modules/pc/jeDate', //日期
            JsTable:'modules/pc/JsTable'//表格
        },
        mobileModules={//移动端模块
            layer:'modules/mb/layer',   //弹窗
            JsForm:'modules/mb/JsForm', //表单
            JsDate:'modules/mb/JsDate', //日期
            JsPage:'modules/mb/JsPage'  //上拉刷新,下拉加载
        };
    //其他信息
    fui.prototype.cache={};
    //设备信息
    fui.prototype.device=function(){
        var lc = navigator.userAgent.toLowerCase(),
            iPad=lc.match(/ipad/i)=='ipad',
            os=lc.match(/iphone os/i)=='iphone os',
            mi=lc.match(/midp/i)=='midp',
            uc7=lc.match(/rv:1.2.3.4/i)=='rv:1.2.3.4',
            uc=lc.match(/ucweb/i)=='ucweb',
            android=lc.match(/android/i)=='android',
            ce=lc.match(/windows ce/i)=='windows ce',
            wm=lc.match(/windows mobile/i)=='windows mobile';
        return !(iPad||os||mi||uc7||uc||android||ce||wm)
    };
    //定义模块(在子模块里面使用)
    fui.prototype.define=function(d,c){
        var t=this,type=typeof d ==='function',mods=function(){
            typeof c==='function' && c(function(app,exports){
                fui[app]=exports;
                config['status'][app]=true
            });
            return this
        };
        type&&(c=d,d=[]);
        t.use(d,mods);
        return t
    };
    //使用(在需要用到此模块的js中引用)
    fui.prototype.use=function(apps,c,exports){
        var t=this,dir=config.dir=config.dir?config.dir:getPath,head=d.getElementsByTagName('head')[0];
        apps=typeof apps==='string'?[apps]:apps;
        if(window.jQuery&&jQuery.fn.on){
            t.each(apps,function(i,v){
                if(v==='jquery'){
                    apps.splice(i,1)
                }
            });
            fui.jquery=fui.$=jQuery
        }
        var item=apps[0],timeout=0,exports=exports||[];
        config.host=config.host||(dir.match(/\/\/([\s\S]+?)\//)||['//'+location.host+'/'])[0];
        function onScriptLoad(e,url){
            var readyRegExp=navigator.platform==='PLaySTATION 3'?/^complete$/:/^(complete|loaded)$/;
            if(e.type==='load'||(readyRegExp.test((e.currentTarget||e.srcElement).readyState))){
                config.modules[item]=url;
                head.removeChild(node);
                (function poll(){
                    if(++timeout>config.timeout*1000/4){
                        return error(item+' is not valid module');
                    }
                    config.status[item]?onCallback():setTimeout(poll,4)
                })();
            }
        }
        function onCallback(){
            exports.push(fui[item]);
            apps.length>1?t.use(apps.slice(1),c,exports):(typeof c==='function'&&c.apply(fui,exports));
        }
        if(apps.length==0){
            return onCallback(),t
        }
        if(!config.modules[item]){
            var node=d.createElement('script'),url=(modules[item]?(dir):'')+(modules[item]||item)+'.js';
            node.async=true;
            node.charset='utf-8';
            node.src=url+function(){
                    var v=config.version===true?(config.v||(new Date()).getTime()):(config.version||'');
                    return v?('?v='+v):"";
                }();
            head.appendChild(node);
            if(node.attachEvent&&!(node.attachEvent.toString&&node.attachEvent.toString().indexOf('[native code]')<0)&&!isOpera){
                node.attachEvent('onreadystatechange',function(e){
                    onScriptLoad(e,url)
                });
            }else{
                node.addEventListener('load',function(e){
                    onScriptLoad(e,url)
                },false)
            }
            config.modules['item']=url;
        }else{
            (function poll(){
                if(++timeout>config.timeout*1000/4){
                    return error(item+' is not a valid module')
                }
                (typeof config.modules[item]==='string'&&config.status[item])?onCallback():setTimeout(poll,4)
            })();
        }
        return t;
    };
    fui.prototype.modules = function(){
        var clone = {};
        for(var o in modules){
            clone[o] = modules[o];
        }
        return clone;
    }();
    //配置(如是否带上版本号)
    fui.prototype.config=function (opts) {
        opts=opts||{};
        for(var k in opts){
            config[k]=opts[k]
        }
        return this;
    };
    //缓存处理
    fui.prototype.cookie={
        set:function(key,value){
            value='object'===typeof value?JSON.stringify(value):value;
            sessionStorage.setItem(key,value)
        },
        get:function(key){
            var _v=sessionStorage.getItem(key);
            try{
                _v=JSON.parse(_v)
            }catch(e){}
            return _v;
        },
        del:function(key){
            sessionStorage.removeItem(key)
        },
        clear:function(){
            sessionStorage.clear()
        }
    };
    //数组操作
    fui.prototype.array={
        join:function(val,arr){
            var na=[];
            for(var x in arr){
                if(val!=arr[x]){
                    na.push(arr[x])
                }
            }
            na.push(val);
            return na
        },
        del:function(val,arr){
            var na=[];
            for(var x in arr){
                if(val!=arr[x]){
                    na.push(arr[x])
                }
            }
            return na
        },
        sort:function(arr,key,desc){
            //fui.array.sort([1,5,2,6,4],'',1);
            //fui.array.sort([{id:2},{id:3},{id:1}],'id');
            var clone=JSON.parse(JSON.stringify(arr||[]));
            var sf=function(v1,v2){
                var reg=/^-?\d+$/;
                if(reg.test(v1)) v1=parseFloat(v1);
                if(reg.test(v2)) v2=parseFloat(v2);
                if(v1 && !v2){return 1}else if(!v1 && v2){return -1}
                if(v1 > v2){return 1}else if (v1 < v2){return -1}else{return 0}
            };
            if(!key){
                clone.sort(function(x,y){
                    return sf(x,y)
                })
            }else{
                clone.sort(function(x,y){
                    var v1=x[key],v2=y[key];
                    return sf(v1,v2)
                })
            }
            desc && clone.reverse();
            return clone;
        },
        same:function(arr){
            var f=false;
            for(var x in arr){
                if(arr[0]!=arr[x]){
                    f=true;
                    break;
                }
            }
            return f?'':arr[0]
        }
    };
    //图片预加载
    fui.prototype.img=function (url,c,error) {
        var img=new Image();
        img.src=url;
        if(img.complete){
            return c(img)
        }
        img.onload=function () {
            img.onload=null;
            c(img)
        };
        img.onerror=function (e) {
            img.onerror=null;
            error(e)
        }
    };
    //单页路由
    fui.prototype.router={
        rs:{},//用来存放注册路由
        way:[],//用于记录hash
        render:function(){
            var t=this;
            window.addEventListener('load',function(){
                t.load()
            });
            window.addEventListener('hashchange',function(){
                t.change()
            });
        },
        map:function(opts){//注册路由
            if(f.isArr(opts)){
                var t=this;
                for(var x=0;x<opts.length;x++){
                    var path=opts[x]['path'].replace(/\s*/g,'');
                    t.rs[path]={
                        path:opts[x].path||"",
                        template:opts[x].template||"",
                        join:opts[x].join||"",
                        back:opts[x].back||"",
                        async:opts[x].async||""
                    };
                    opts[x]['async']?t.rs[path]['fn']=-1:'';
                }
            }else{
                error('路由配置不对')
            }
        },
        load:function(){
            var nh=f.gu();
            if(this.rs[nh.path]){
                this.way=[nh.path];
                this.refresh(nh)
            }else{
                location.hash='/index'
            }
        },
        change:function(){
            var nh=f.gu(),t=this;
            if(t.rs[nh.path]){
                if(t.way[t.way.length-1]==nh.path){
                    t.call(1,nh)
                }else{
                    if(t.way.length>1&&t.way[t.way.length-2]==nh.path){
                        t.exit(nh);
                        t.refresh(nh,2)
                    }else{
                        t.join(nh.path);
                        t.refresh(nh,1)
                    }
                }
            }
        },
        join:function(p){
            this.way.push(p)
        },
        exit:function(){
            this.way.pop()
        },
        call:function(type,nh){
            var t=this;
            if(type==1){
                var join;
                try{
                    join=eval(t.rs[nh.path]['join']);
                    join(nh['query']);
                }catch (e){}
            }else{
                var back;
                try{
                    back=t.rs[nh.path]['back']?eval(t.rs[nh.path]['back']):eval(t.rs[nh.path]['join']);
                    back(nh['query']);
                }catch (e){}
            }
        },
        refresh:function(nh,type){
            var t=this;
            type=type||1;
            if(t.rs[nh.path].fn==-1){
                var _b=document.getElementsByTagName('body')[0];
                var _s=document.createElement('script');
                _s.type='text/javascript';
                _s.src=t.rs[nh.path]['async'];
                _s.async=true;
                _s.onload=function(){
                    t.rs[nh.path].fn=1;
                    t.call(type,nh)
                };
                _b.appendChild(_s)
            }else{
                t.call(type,nh)
            }
        }
    };
    //原生js类名操作(在没有引入jq时,需要对class进行操作时可用,也可等加载完成,用jq的对应操作)
    fui.prototype.hasClass=function(element,cls){
        return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
    };
    fui.prototype.addClass=function(element,cls){
        var oc=element.className,
            bc=(oc!= '')?' ':'';
        element.className=oc+bc+cls;
    };
    fui.prototype.removeClass=function(element,cls){
        var oc=' '+element.className+' ';
        oc=oc.replace(/\s+/gi,' ');
        element.className=oc.replace(' '+cls+' ',' ').replace(/(^\s+)|(\s+$)/g,'');
    };
    //ajax数据请求封装
    fui.prototype.ajax=function(url,d,c,b,type){
        var t=this,load;
        if(t.cache[url]) return layer?layer.msg('数据请求中,请不要重复提交'):alert('数据请求中,请不要重复提交');
        var xhr=fui.$.ajax({
            type:type||'post',
            url:url,
            data:d,
            timeout:10000,
            dataType:'json',
            beforeSend:function(){
                load=layer?layer.load(3):"";
                t.cache[url]=true;
                b?b():''
            },
            success:function(r){
                layer?layer.close(load):'';
                t.cache[url]=false;
                if(r.code==1){
                    c?c(r.result):""
                }else{
                    layer?layer.msg('错误：'+r.msg):alert('错误：'+r.msg)
                }
            },
            error:function(){
                layer?layer.close(load)&&layer.msg('请求失败'):alert('请求失败');
                t.cache[url]=false;
            },
            complete:function(XMLHttpRequest,status){
                if(status=='timeout'){
                    t.cache[url]=false;
                    xhr.abort();
                    layer?layer.close(load)&&layer.msg('请求超时'):alert('请求超时')
                }
            }
        })
    };
    win.fui=new fui();
}(window);







